/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.form; import java.beans.*; import org.openide.explorer.propertysheet.editors.EnhancedPropertyEditor; import org.openide.nodes.*; /** A Multiplexing PropertyEditor used in the form editor. * Allows multiple editors to be used with one currently selected. * * @author Ian Formanek */ public class FormPropertyEditor implements PropertyEditor, PropertyChangeListener, EnhancedPropertyEditor { // ----------------------------------------------------------------------------- // Private Variables private Object value; private Object source; private RADComponent radComponent; private RADComponent.RADProperty radProperty; private PropertyEditor modifiedEditor; private Class propertyType; private PropertyEditor[] allEditors; /** * @associates PropertyChangeListener */ private java.util.Vector listeners; // ----------------------------------------------------------------------------- // Constructor /** Crates a new FormPropertyEditor */ FormPropertyEditor(RADComponent radComponent, Class propertyType, RADComponent.RADProperty radProperty) { source = this; this.radComponent = radComponent; this.radProperty = radProperty; this.propertyType = propertyType; modifiedEditor = radProperty.getCurrentEditor (); if (modifiedEditor instanceof FormAwareEditor) { ((FormAwareEditor)modifiedEditor).setRADComponent (radComponent, radProperty); } if (modifiedEditor instanceof org.openide.explorer.propertysheet.editors.NodePropertyEditor) { ((org.openide.explorer.propertysheet.editors.NodePropertyEditor)modifiedEditor).attach (new org.openide.nodes.Node[] { radComponent.getNodeReference () }); } modifiedEditor.addPropertyChangeListener (this); } Class getPropertyType () { return propertyType; } RADComponent getRADComponent () { return radComponent; } RADComponent.RADProperty getRADProperty () { return radProperty; } PropertyEditor getModifiedEditor () { return modifiedEditor; } void commitModifiedEditor () { radProperty.setCurrentEditor (modifiedEditor); if (radComponent.getNodeReference () != null) radComponent.getNodeReference ().notifyPropertySetsChange (); } void setModifiedEditor (PropertyEditor editor) { modifiedEditor.removePropertyChangeListener (this); modifiedEditor = editor; modifiedEditor.addPropertyChangeListener (this); } // ----------------------------------------------------------------------------- // PropertyChangeListener implementation public void propertyChange (PropertyChangeEvent evt) { value = modifiedEditor.getValue (); // [PENDING - modified or current?] } // ----------------------------------------------------------------------------- // PropertyEditor implementation /** * Set (or change) the object that is to be edited. * @param value The new target object to be edited. Note that this * object should not be modified by the PropertyEditor, rather * the PropertyEditor should create a new object to hold any * modified value. */ public void setValue(Object newValue) { Object oldValue = value; value = newValue; modifiedEditor.setValue (value); firePropertyChange (); } /** * Gets the value of the property. * * @return The value of the property. */ public Object getValue() { return value; } // ----------------------------------------------------------------------------- /** * Determines whether the class will honor the painValue method. * * @return True if the class will honor the paintValue method. */ public boolean isPaintable() { return modifiedEditor.isPaintable (); } /** * Paint a representation of the value into a given area of screen * real estate. Note that the propertyEditor is responsible for doing * its own clipping so that it fits into the given rectangle. * <p> * If the PropertyEditor doesn't honor paint requests (see isPaintable) * this method should be a silent noop. * * @param gfx Graphics object to paint into. * @param box Rectangle within graphics object into which we should paint. */ public void paintValue(java.awt.Graphics gfx, java.awt.Rectangle box) { modifiedEditor.paintValue (gfx, box); } // ----------------------------------------------------------------------------- /** * This method is intended for use when generating Java code to set * the value of the property. It should return a fragment of Java code * that can be used to initialize a variable with the current property * value. * <p> * Example results are "2", "new Color(127,127,34)", "Color.orange", etc. * * @return A fragment of Java code representing an initializer for the * current value. */ public String getJavaInitializationString() { return modifiedEditor.getJavaInitializationString (); } // ----------------------------------------------------------------------------- /** * Gets the property value as a string suitable for presentation * to a human to edit. * * @return The property value as a string suitable for presentation * to a human to edit. * <p> Returns "null" is the value can't be expressed as a string. * <p> If a non-null value is returned, then the PropertyEditor should * be prepared to parse that string back in setAsText(). */ public String getAsText() { return modifiedEditor.getAsText (); } /** * Sets the property value by parsing a given String. May raise * java.lang.IllegalArgumentException if either the String is * badly formatted or if this kind of property can't be expressed * as text. * * @param text The string to be parsed. */ public void setAsText(String text) throws java.lang.IllegalArgumentException { modifiedEditor.setAsText (text); } // ----------------------------------------------------------------------------- /** * If the property value must be one of a set of known tagged values, * then this method should return an array of the tag values. This can * be used to represent (for example) enum values. If a PropertyEditor * supports tags, then it should support the use of setAsText with * a tag value as a way of setting the value. * * @return The tag values for this property. May be null if this * property cannot be represented as a tagged value. * */ public String[] getTags() { return modifiedEditor.getTags (); } // ----------------------------------------------------------------------------- /** * A PropertyEditor may chose to make available a full custom Component * that edits its property value. It is the responsibility of the * PropertyEditor to hook itself up to its editor Component itself and * to report property value changes by firing a PropertyChange event. * <P> * The higher-level code that calls getCustomEditor may either embed * the Component in some larger property sheet, or it may put it in * its own individual dialog, or ... * * @return A java.awt.Component that will allow a human to directly * edit the current property value. May be null if this is * not supported. */ public java.awt.Component getCustomEditor() { return new FormCustomEditor (this); } /** * Determines whether the propertyEditor can provide a custom editor. * * @return True if the propertyEditor can provide a custom editor. */ public boolean supportsCustomEditor() { PropertyEditor[] editors = getAllEditors (); if (editors.length > 1) return true; // we must allow to choose the editor even if none of them supports custom editing if (editors.length == 1) return editors[0].supportsCustomEditor (); return false; } PropertyEditor[] getAllEditors () { if (allEditors == null) { PropertyEditor expliciteEditor = radProperty.getExpliciteEditor (); allEditors = FormPropertyEditorManager.getAllEditors (propertyType, false); if (expliciteEditor != null) { PropertyEditor[] newAllEditors = new PropertyEditor[allEditors.length + 1]; newAllEditors[0] = expliciteEditor; System.arraycopy (allEditors, 0, newAllEditors, 1, allEditors.length); allEditors = newAllEditors; } } return allEditors; } // ----------------------------------------------------------------------------- // EnhancedPropertyEditor implementation /** Get an in-place editor. * @return a custom property editor to be shown inside the property * sheet */ public java.awt.Component getInPlaceCustomEditor () { if (modifiedEditor instanceof EnhancedPropertyEditor) { return ((EnhancedPropertyEditor)modifiedEditor).getInPlaceCustomEditor (); } else { return null; } } /** Test for support of in-place custom editors. * @return <code>true</code> if supported */ public boolean hasInPlaceCustomEditor () { if (modifiedEditor instanceof EnhancedPropertyEditor) { return ((EnhancedPropertyEditor)modifiedEditor).hasInPlaceCustomEditor (); } else { return false; } } /** Test for support of editing of tagged values. * Must also accept custom strings, otherwise you may may specify a standard property editor accepting only tagged values. * @return <code>true</code> if supported */ public boolean supportsEditingTaggedValues () { if (modifiedEditor instanceof EnhancedPropertyEditor) { return ((EnhancedPropertyEditor)modifiedEditor).supportsEditingTaggedValues (); } else { return false; } } // ----------------------------------------------------------------------------- /** * Register a listener for the PropertyChange event. The class will * fire a PropertyChange value whenever the value is updated. * * @param listener An object to be invoked when a PropertyChange * event is fired. */ public synchronized void addPropertyChangeListener(PropertyChangeListener listener) { if (listeners == null) { listeners = new java.util.Vector(); } listeners.addElement(listener); } /** * Remove a listener for the PropertyChange event. * * @param listener The PropertyChange listener to be removed. */ public synchronized void removePropertyChangeListener(PropertyChangeListener listener) { if (listeners == null) { return; } listeners.removeElement(listener); } /** * Report that we have been modified to any interested listeners. * * @param source The PropertyEditor that caused the event. */ void firePropertyChange() { java.util.Vector targets; synchronized (this) { if (listeners == null) { return; } targets = (java.util.Vector) listeners.clone(); } PropertyChangeEvent evt = new PropertyChangeEvent(this, null, null, null); for (int i = 0; i < targets.size(); i++) { PropertyChangeListener target = (PropertyChangeListener)targets.elementAt(i); target.propertyChange(evt); } } } /* * Log * 18 Gandalf 1.17 1/10/00 Ian Formanek Fixed bug 4935 - When * the property editor type is changed for JavaBean's properties in the * Component Inspector using the custom editor, the property sheet is not * updated and it is necessary to swith to other component and back to * have it properly render the property value. * 17 Gandalf 1.16 10/23/99 Ian Formanek NO SEMANTIC CHANGE - Sun * Microsystems Copyright in File Comment * 16 Gandalf 1.15 10/6/99 Ian Formanek Fixed bug 3494 - When * creating EnhancedPropertyEditor with inplace custom editor * (JPasswordField), it doesn't lost the focus when enter was pressed. * 15 Gandalf 1.14 9/12/99 Ian Formanek FormAwareEditor.setRADComponent * changes * 14 Gandalf 1.13 8/17/99 Ian Formanek no semantic change * 13 Gandalf 1.12 8/17/99 Ian Formanek Fixed work with multiple * property editors * 12 Gandalf 1.11 8/1/99 Ian Formanek NodePropertyEditor * employed * 11 Gandalf 1.10 8/1/99 Ian Formanek cleaned usage of * modified editor * 10 Gandalf 1.9 7/23/99 Ian Formanek Caching editor classes * 9 Gandalf 1.8 6/30/99 Ian Formanek reflecting change in * enhanced property editors interfaces * 8 Gandalf 1.7 6/24/99 Ian Formanek Improved * FormPropertyEditor towards accepting multiple editors * 7 Gandalf 1.6 6/22/99 Ian Formanek Further tweaked for * multiple (custom) editors * 6 Gandalf 1.5 6/22/99 Ian Formanek * 5 Gandalf 1.4 6/22/99 Ian Formanek Fixed setting * FormAwareEditor * 4 Gandalf 1.3 6/9/99 Ian Formanek ---- Package Change To * org.openide ---- * 3 Gandalf 1.2 5/31/99 Ian Formanek Removed dumpStack * 2 Gandalf 1.1 5/30/99 Ian Formanek * 1 Gandalf 1.0 5/24/99 Ian Formanek * $ */